<!-- 课文跟读 -->
<template>
    <AppHeader title="例词跟读" :banAnimate="true" backgroundColor="#ffffff">
        <template #left>
            <img @click="onClickLeft" src="@/assets/phoneticPractice/返回图标@3x.png" width="9" height="18" />
        </template>
    </AppHeader>
    <div class="container-practice" v-if="state.practoceList.resource && state.practoceList.resource.length">
        <div class="container-height"></div>
        <div class="practice-top">
            <div class="practice-top-currentPage">{{ currentPage }}<span>/{{ state.practoceList.resource.length }}</span></div>
            <div class="practice-top-slider">
                <Slider v-model="currentPage" min="0" :max="practoceList.resource.length || 1000" active-color="#0CB76C">
                </Slider>
            </div>
            <div class="practice-top-switch">
                <div :class="active === 2 ? 'active' : ''" @click="switchManual">自动</div>
                <div :class="active === 1 ? 'active' : ''" @click="switchManual">手动</div>
            </div>
        </div>
        <div class="container-text" v-for="(item,index) in state.practoceList.resource" :key="index" v-show = "currentPage - 1 === index">
            <span v-html="item.name"></span>
        </div>

        <div class="practiceFractionBox">
			<div class="practiceFraction" v-if="recordingStatus=='ended'&&wordsDetail.sourceObj">
				<div :class="autoColor(wordsDetail.sourceObj.total_score)">
					{{wordsDetail.sourceObj.total_score}}分
				</div>
				<img src="@/assets/images/brushWords/scoreSrcRed.png"
					v-if="wordsDetail.sourceObj.total_score<60&&recordingStatus=='ended'" />
				<img src="@/assets/images/brushWords/scoreSrcYellow.png"
					v-if="(wordsDetail.sourceObj.total_score>60&&wordsDetail.sourceObj.total_score<80)&&recordingStatus=='ended'" />
				<img src="@/assets/images/brushWords/scoreSrcGreed.png"
					v-if="wordsDetail.sourceObj.total_score>80&&recordingStatus=='ended'" />
				<div class="context">
					<div class="label">完成度</div>
					<div :class="autoColor(wordsDetail.sourceObj.integrity_score)">
						{{wordsDetail.sourceObj.integrity_score }}
					</div>
				</div>
				<div class="context">
					<div class="label">流利度</div>
					<div :class="autoColor(wordsDetail.sourceObj.fluency_score)">
						{{wordsDetail.sourceObj.fluency_score }}
					</div>
				</div>
				<div class="context">
					<div class="label">准确度</div>
					<div :class="autoColor(wordsDetail.sourceObj.accuracy_score)">
						{{wordsDetail.sourceObj.accuracy_score}}
					</div>
				</div>
			</div>
		</div>

        <div class="practiceButton">
			<div class="wordsVoice" v-if="active == 1">
				<img @click="onlyPlayAudio" :src="playImgSrc" />
			</div>
			<!-- 弹性盒占位 -->
			
			<div class="wordsPlay" v-if="active == 1">
				<!-- @click="tapeClick" -->
				<div class="circle-container" v-if="recordingStatus == 'recording'">
					<svg class="circle-progress" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
						<circle class="circle-bg" cx="18" cy="18" r="16" fill="none" stroke="#ffffff"
							stroke-width="1" />
						<circle class="circle" cx="18" cy="18" r="16" fill="none" stroke="#0CB76C" stroke-width="1"
							stroke-dasharray="100.48" stroke-dashoffset="100.48" />
					</svg>
					<img :src="tapeImgSrc" style="position: absolute;" />
				</div>
				<img src="@/assets/phoneticPractice/录音@3x.png" v-if="recordingStatus != 'recording'"
					@click="tapeClick" />
			</div>
			<div class="myVoice" v-if="active == 1">
				<div class="circle-container1" v-if="wordsDetail.video">
					<svg class="circle-progress" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" v-if="isPlayMyVideo">

						<circle :class="isPlayMyVideo ? 'circle1' : ''" cx="18" cy="18" r="16" fill="none"
							stroke="#0CB76C" stroke-width="1" stroke-dasharray="100.48" stroke-dashoffset="100.48" />
					</svg>
					<img src="@/assets/phoneticPractice/播放@3x.png" style="position: absolute;" @click="playRecording"/>
				</div>
                <div @click="completeClick1" class="practice-button-complete" v-if="recordingStatus == 'recording'">完成录音</div>
			</div>
			
			<div class="wordsPlay" v-if="active == 2">
				<div class="circle-container" v-if="recordingStatus == 'recording'">
					<svg class="circle-progress" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
						<circle class="circle-bg" cx="18" cy="18" r="16" fill="none" stroke="#ffffff"
							stroke-width="1" />
						<circle class="circle" cx="18" cy="18" r="16" fill="none" stroke="#0CB76C" stroke-width="1"
							stroke-dasharray="100.48" stroke-dashoffset="100.48" />
					</svg>
					<img :src="tapeImgSrc" style="position: absolute;" />
				</div>
				<div class="circle-container" v-if="recordingStatus == 'playing'">
					<svg class="circle-progress" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
						<circle class="circle-bg" cx="18" cy="18" r="16" fill="none" stroke="#ffffff"
							stroke-width="1" />
						<circle class="circle1" cx="18" cy="18" r="16" fill="none" stroke="#0CB76C" stroke-width="1"
							stroke-dasharray="100.48" stroke-dashoffset="100.48" />
					</svg>
					<img :src="tapeImgSrc" style="position: absolute;" />
				</div>
                <!-- <div @click="completeClick1" class="practice-button-complete" v-if="recordingStatus == 'recording'" style="margin-left:20px;">完成录音</div> -->
			</div>
		</div>
        <div class="practiceBottom" v-if="recordingStatus=='ended' && active === 1">
			<div @click="prevclick" class="next">上一个</div>
			<!-- <div @click="againRead" class="again">重读</div> -->
            <div @click="nextclick" class="next">{{currentPage == state.practoceList.resource.length ? '完成' : '下一个' }}</div>
		</div>
		<div class="practiceBottom" v-if="active === 2">
			<img class="practice-bottom-img" :src="bottomImgSrc" @click="automaticPlay" />
			<div @click="nextclick" class="next" v-if="recordingStatus=='ended' && currentPage == state.practoceList.resource.length">完成</div>
		</div>
    </div>
    <van-overlay :show="recordingStatus=='evaluating'">
        <div class="loading">
            <van-loading type="spinner" />
            <div class="text">评分中...</div>
        </div>
    </van-overlay>
    <Overlay :show="automaticOverlay">
        <div class="automaticOverlay">
            <div class="automaticOverlay-context" v-if="active == 1">手动模式可重读跟读，需要您自主操作进行跟读流程,确定切换吗?</div>
            <div class="automaticOverlay-context" v-if="active == 2">关闭手动模式将自动进行跟读流程，确认关闭吗?</div>
            <div class="automaticOverlay-button">
                <div @click="automaticOverlay = false">取消</div>
                <div @click="switchAutomatic">确定</div>
            </div>
        </div>
    </Overlay>
    <audio ref="audioElement" :src="audioSrc" @ended="playEnded"></audio>
    <audio ref="" src="@/assets/ding.mp3"></audio>
</template>

<script setup>
import { Slider, Overlay } from "vant";
import AppHeader from '../../components/AppHeader.vue'
import { useRouter, useRoute } from 'vue-router'
import { onMounted, reactive, ref, toRefs, nextTick, watch,onBeforeUnmount,onUnmounted } from 'vue'
import IatRecorder from '@/utils/iatRecorder'
import scoreSrcRed from "@/assets/phoneticPractice/分数-红@3x.png"
import scoreSrcYellow from "@/assets/phoneticPractice/分数-黄@3x.png"
import scoreSrcGreed from "@/assets/phoneticPractice/分数-绿@3x.png"
import {uploadFiles} from "@/api/brushWords.js";
import { saveExercise,questions} from "@/api/writtenTest";
const router = useRouter()
const route = useRoute()
const onClickLeft = () => {
    router.go(-1)
}
const currentPage = ref(1)
const active = ref(1)
const automaticOverlay = ref(false)

const title = route.query.title;
const state = reactive({
    practoceList: {},
    sourceObj: {}
})
const wordsDetail = ref({
		words_detail: {}
	}) //单词详情信息
const isPlayWords = ref(false) //是否正在播放单词
const recordingStatus = ref('notStarted') //录音状态 notStarted未开始  recording 录音中 ended 已结束 evaluating评测中
const audioElement = ref(null)
let audioSrc 
let stream;
var time = 0
const tapeShow = ref(true)
let iatRecorder = new IatRecorder()
let mediaRecorder;
let recordedChunks = [];
let thisType 
let sumbitObj = []
const playImgSrc = ref('')
const tapeImgSrc = ref('')
const bottomImgSrc = ref('')
const isPlayMyVideo = ref(false)
let myAudio
onMounted(async () => {
    thisType = route.query.type || 'follow'
    const imgUrl =  await import('@/assets/phoneticPractice/话筒效果-2.gif')
    playImgSrc.value = imgUrl.default
    const playModule1 = await import('@/assets/images/brushWords/isRecording.gif')
    tapeImgSrc.value = playModule1.default
    const bottomModule = await import('@/assets/phoneticPractice/暂停@3x.png')
    bottomImgSrc.value = bottomModule.default
    if(route.query.jsonurl){
        questions({
            resourceFile:route.query.jsonurl,
            url: '/file/soundmark/res/'
        }).then(res=>{
            state.practoceList = res.data
            getWordsDetail()
        })
        return
    }
    state.practoceList = JSON.parse(sessionStorage.getItem("soundmark"))
    getWordsDetail()
})
var timer = setInterval(async ()=>{
    time ++
},1000)
onBeforeUnmount(()=>{
    clearInterval(timer)
    timer = null
})
onUnmounted(() => {
    if (mediaRecorder) {
        stopRecording() //结束录音
    }
    if (iatRecorder) {
        iatRecorder.stop()
    }
    if(audioSrc){
        audioSrc.pause();
        audioSrc.currenTime = 0
    }
    if(myAudio){
        myAudio.pause()
        myAudio.currenTime = 0
    }
    if(onlyAudio){
        onlyAudio.pause()
        onlyAudio.currenTime = 0
    }
    clearTimeout(videoTimeoutVal.value)
    clearTimeout(sourceTimeoutVal.value)
})
const againRead = () => {
    wordsDetail.value.sourceObj = ''
    recordingStatus.value = 'notStarted'
    playAudio()
    // tapeClick()
}
let onlyAudio 
const onlyPlayAudio = async () => {
    if (recordingStatus.value != 'ended') {
        return
    }
    // isOnlyPlayAudio.value = true
    const playModule = await import('@/assets/phoneticPractice/话筒效果-2.gif')
    playImgSrc.value = playModule.default
    onlyAudio = new Audio( state.practoceList.resmain +'/'+ state.practoceList.resource[currentPage.value-1].audioUrl);
    onlyAudio.play();
    onlyAudio.addEventListener('ended', async function() {
        const playModule = await import('@/assets/phoneticPractice/声音@3x.png')
        playImgSrc.value = playModule.default
    });
}
// 播放音频
const playAudio = async (type) => {
    if (type == 'word') {
        audioSrc =  new Audio(state.practoceList.resmain +'/'+ state.practoceList.resource[currentPage.value-1].audioUrl)
        isPlayWords.value = true
    }
    setTimeout(async () => {
        await audioSrc.play()
    }, 1000)
    audioSrc.addEventListener('ended', function() {
        playEnded()
    });
}
//播放结束
const playEnded = async () => {
    isPlayMyVideo.value = false //结束自己的音频播放
    isPlayWords.value = false
    audioSrc.pause();
    audioSrc.currenTime = 0
    nextTick(async () => {
        if(isPlay.value === 'stop'){
            tapeClick()
        }
    })
}
const playRecording = async () => {
    myAudio = new Audio( wordsDetail.value.video);
    myAudio.play();
    isPlayMyVideo.value = true
    myAudio.addEventListener('ended', function() {
        isPlayMyVideo.value = false
    });
}
const autoColor = (num) => {
    if (num < 60) {
        return 'autoRed' //#FA192C
    } else if (num > 60 && num < 80) {
        return 'autoYellow'//#FF9917
    } else if (num > 80) {
        return 'autoGreed'//#0CB76C
    }
}
const getWordsDetail = () =>{
    iatRecorder = new IatRecorder({ text: state.practoceList.resource[currentPage.value - 1].name.split('{')[0] })
    if(thisType === 'follow'){  //跟读
        playAudio('word')
    }else{  //朗读
        nextTick(async () => {
            tapeClick()
        })
    }
}
//上一个
const prevclick = async () => {
    if(currentPage.value === 1){
        return showToast('已经是第一个了')
    }

    const imgUrl =  await import('@/assets/phoneticPractice/话筒效果-2.gif')
    playImgSrc.value = imgUrl.default
    if(active.value === 2){
        const imgUrl1 =  await import('@/assets/phoneticPractice/读@3x.png')
        tapeImgSrc.value = imgUrl1.default
    }
    wordsDetail.value.video = ''
    isPlay.value = 'stop'
    currentPage.value --
    recordedChunks = []
    recordingStatus.value = active.value === 2 ? 'playing' : 'notStarted'
    getWordsDetail()
}
// 下一个
const nextclick = async () => {
    if (currentPage.value == state.practoceList.resource.length) {
        //提交数据
        var params = {
            source_id:state.practoceList.source_id,
            question_type:0,
            question_source_type:5,
            use_time:time,
            total_score:100,
            json:JSON.stringify(state.practoceList),
            answer_score_json:JSON.stringify(sumbitObj)
        }
        sessionStorage.setItem('params',JSON.stringify(params))
        router.push({
            path: '/phoneticSymbol/handHomework',
            query: {
                title: '例词跟读'
            }
        })
        return
    }
    const imgUrl =  await import('@/assets/phoneticPractice/话筒效果-2.gif')
    playImgSrc.value = imgUrl.default
    if(active.value === 2){
        const imgUrl1 =  await import('@/assets/phoneticPractice/读@3x.png')
        tapeImgSrc.value = imgUrl1.default
    }
    wordsDetail.value.video = ''
    isPlay.value = 'stop'
    currentPage.value++
    recordedChunks = []
     recordingStatus.value = active.value === 2 ? 'playing' : 'notStarted'
    getWordsDetail()
}

function fileToBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();

        reader.readAsDataURL(file);

        reader.onload = () => resolve(reader.result);
        reader.onerror = error => reject(error);
    });
}

//语音识别
const videoTimeoutVal = ref()
const tapeClick = async () => {
    // practoceList[currentPage-1].words
    startRecording()//录音
    recordingStatus.value = 'recording'
    const playModule = await import('@/assets/phoneticPractice/声音@3x.png')
    playImgSrc.value = playModule.default
    const playModule1 = await import('@/assets/images/brushWords/isRecording.gif')
    tapeImgSrc.value = playModule1.default
    iatRecorder.start()
    videoTimeoutVal.value = setTimeout(async () => {
        recordingStatus.value = 'evaluating'
        completeClick()
    }, 8000);
}
const isPlay = ref('stop') //自动播放状态
const automaticPlay = async () => {
    if (isPlay.value == 'stop') {
        const bottomModule = await import('@/assets/phoneticPractice/形状@3x.png')
        bottomImgSrc.value = bottomModule.default
        isPlay.value = 'play'
        recordingStatus.value = 'notStarted'
        if (mediaRecorder) {
            stopRecording() //结束录音
        }
        if (iatRecorder) {
            iatRecorder.stop()
        }
        audioSrc.pause();
        audioSrc.currenTime = 0
        clearTimeout(videoTimeoutVal.value)
        videoTimeoutVal.value = null
        clearTimeout(sourceTimeoutVal.value)
        sourceTimeoutVal.value = null
    } else {
        const bottomModule = await import('@/assets/phoneticPractice/暂停@3x.png')
        bottomImgSrc.value = bottomModule.default
        const imgUrl1 =  await import('@/assets/phoneticPractice/读@3x.png')
        tapeImgSrc.value = imgUrl1.default
        isPlay.value = 'stop'
        recordingStatus.value = 'playing'
        getWordsDetail()
    }
}
const completeClick1 = async () => {
    clearTimeout(videoTimeoutVal.value)
    completeClick()
}
//完成识别
const sourceTimeoutVal = ref()
const completeClick = async () => {
    recordingStatus.value = 'evaluating'
    const tapeModule = await import('@/assets/phoneticPractice/录音@3x.png')
    tapeImgSrc.value = tapeModule.default
    isPlay.value = 'play'
    iatRecorder.stop()
    stopRecording() //结束录音
    setTimeout(async () => {
        recordingStatus.value = 'ended'
        sumbitObj[currentPage.value-1] = {
            myvideosource:'',
            score:'',
            name:state.practoceList.resource[currentPage.value-1].name,
            questionid:{
                version_id:state.practoceList.source_id
            },
            words:wordsDetail.value.words_detail.words,
            symbol:wordsDetail.value.words_detail.symbol,
            pretations:wordsDetail.value.words_detail.pretations
        }
        if (iatRecorder.getScoreObj()) {
            wordsDetail.value.sourceObj = {
                total_score: Math.round(iatRecorder.getScoreObj().total_score),
                accuracy_score: Math.round(iatRecorder.getScoreObj().accuracy_score),
                fluency_score: Math.round(iatRecorder.getScoreObj().fluency_score),
                integrity_score: Math.round(iatRecorder.getScoreObj().integrity_score)
            }
            
            if (wordsDetail.value.sourceObj.total_score == 0) {
                sourceTimeoutVal.value = setTimeout(() => {
                    // tapeClick()
                }, 1000)
                return showToast('录音失败请重读')
            }
            let userInfo = localStorage.getItem('userInfo')
            let username = userInfo ? JSON.parse(userInfo).username : ''
            const blob = new Blob(recordedChunks, {
                type: "audio/webm;codecs=opus"
            });
            var file = new File([blob], username + '-' + wordsDetail.value.words_detail.words +
                Date
                .now() +
                '.MP3', {
                    type: 'audio/x-mpeg',
                    lastModified: Date.now()
                });
            let formData = new FormData();
            formData.append('file', file);
            uploadFiles(formData).then(res => {
                wordsDetail.value.video = res.data.fullurl
                sumbitObj[currentPage.value-1]['myvideosource'] = res.data.fullurl || ''
                sumbitObj[currentPage.value-1]['url'] = res.data.fullurl || ''
            })
            sumbitObj[currentPage.value-1]['sourceObj']=wordsDetail.value.sourceObj
            sumbitObj[currentPage.value-1]['mission_id']=route.query.mission_id || ''
            sumbitObj[currentPage.value-1]['score']=wordsDetail.value.sourceObj.total_score
            sumbitObj[currentPage.value-1]['color']=wordsDetail.value.sourceObj.total_score < 60 ? 'red' : 60 < wordsDetail.value.sourceObj.total_score && wordsDetail.value.sourceObj.total_score < 80 ?  'yellow' : 'green'
            if (currentPage.value < state.practoceList.resource.length && active.value === 2) {
                setTimeout(() => {
                    nextclick()
                }, 3000)
            }
        } else {
            showToast('录音失败请重读')
            // tapeClick()
            wordsDetail.value.sourceObj = null
        }
    }, 5000);

}

const destroyRecord = async () => {
    // 终止流（这可以让浏览器上正在录音的标志消失掉）
    stream.getTracks().forEach(track => track.stop());
    stream = null;
}

const startRecording = async () => {
    const audio = new Audio('https://oss.bigchun.com/file/ding.mp3');
    await audio.play();
    try {
        recordedChunks = []
        stream = await navigator.mediaDevices.getUserMedia({
            audio: true
        });
        mediaRecorder = new MediaRecorder(stream);

        mediaRecorder.addEventListener('dataavailable', event => {
            recordedChunks.push(event.data);
        });

        mediaRecorder.start();
    } catch (error) {
        console.error('获取媒体流错误:', error);
    }
};

const stopRecording = () => {
    state.practoceList.resource[currentPage.value - 1].recordedChunks = recordedChunks
    mediaRecorder.stop();
};


const blobToBase64 = (blob) => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onload = () => resolve(reader.result);
        reader.onerror = reject;
    });
};


const switchManual = async () => {
    audioSrc.pause();
    audioSrc.currenTime = 0
    automaticOverlay.value = true
}
const switchAutomatic = async ()=>{
    if (active.value == 2) {
        recordingStatus.value = 'notStarted'
        active.value = 1
    } else {
        recordingStatus.value = 'playing'
        active.value = 2
    }
    if (mediaRecorder) {
        stopRecording() //结束录音
    }
    if (iatRecorder) {
        iatRecorder.stop()
    }
    
    automaticOverlay.value = false
    clearTimeout(videoTimeoutVal.value)
    clearTimeout(sourceTimeoutVal.value)
    isPlay.value = 'stop'
    const bottomModule = await import('@/assets/phoneticPractice/暂停@3x.png')
    bottomImgSrc.value = bottomModule.default
    const imgUrl1 =  await import('@/assets/phoneticPractice/读@3x.png')
    tapeImgSrc.value = imgUrl1.default
    const imgUrl =  await import('@/assets/phoneticPractice/话筒效果-2.gif')
    playImgSrc.value = imgUrl.default
    getWordsDetail()
}


const { practoceList, sourceObj } = toRefs(state)

</script>

<style scoped lang="scss">
.loading {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ffffff;
    height: 100%;
    font-size: 18px;

    .text {
        margin-left: 10px;
    }
}
.circle-container {
		width: 70px;
		/* 容器大小，根据需要调整 */
		height: 70px;
		display: flex;
		align-items: center;
		justify-content: center;
	}
.automaticOverlay {
    width: 345px;
    height: 184px;
    background: #FFFFFF;
    border-radius: 15px;
    color: #333333;
    font-size: 16px;
    line-height: 32px;
    top: 0;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    .automaticOverlay-context {
        margin: 30px 20px;
    }

    .automaticOverlay-button {
        margin: 0 20px 30px 20px;
        display: flex;
        justify-content: space-between;
        align-items: center;

        div {
            width: 135px;
            height: 40px;
            line-height: 40px;
            text-align: center;
        }

        div:nth-child(1) {
            border: 1px solid #8E8E8E;
            border-radius: 22.5px;
            font-size: #333333;
        }

        div:nth-child(2) {
            border-radius: 22.5px;
            color: #FFFFFF;
            background: linear-gradient(to left, #29F19C, #02A1F9);
        }
    }

}
.practice-button-complete {
    // margin-right: 68px;
    font-size: 16px;
    color: #0CB76C;

}
.container-practice {
    height: 100%;
    text-align: center;

    .container-height {
        height: 46px;
    }

    .practice-top {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 10px;

        // margin: 0 12px;
        // margin-top: 15px;
        .practice-top-currentPage {
            font-size: 16px;
            color: #0CB76C;

            span {
                color: #8E8E8E;
            }
        }

        .practice-top-slider {
            min-width: 234px;
            flex: 1;
            margin: 0 10px;

        }

        .practice-top-switch {

            // width: 72px;
            height: 22px;
            border-radius: 12px;
            font-size: 12px;
            background: #0CB76C;

            div {
                display: inline-block;
                width: 36px;
                height: 100%;
                color: #FFFFFF;
                text-align: center;
                line-height: 22px;
            }

            .active {
                height: 20px;
                color: #0CB76C;
                border: 1px solid #0CB76C;
                background: #FFFFFF;
                border-radius: 12px;
            }
        }
    }

    .container-text {
        margin-top: 20px;
        height: 310px;
        padding: 0 10px;
        text-align: left;
        font-family: PingFangSC, PingFang SC;
        font-weight: 500;
        font-size: 18px;
        color: #333333;
        line-height: 44px;
    }

    .practice-context {
        height: 165px;
        font-size: 14px;
        color: #8E8E8E;
        line-height: 20px;
        display: flex;
        flex-direction: column;
        align-items: center;

        .practice-context-title {
            color: #333333;
            font-size: 32px;
            line-height: 45px;

        }

        .practice-context-context {
            margin-top: 10px;
        }

        .practice-context-bottom {
            margin-top: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;

            div {
                white-space: pre-line;
            }
        }

    }

    
    .practice-bottom {
        position: fixed;
        width: 100%;
        bottom: 20px;
        display: flex;
        align-items: center;
        justify-content: space-around;


        .practice-bottom-prev {
            font-family: PingFangSC, PingFang SC;
            font-weight: 500;
            font-size: 16px;
            color: #0CB76C;
            line-height: 22px;
            text-align: right;
            font-style: normal;
        }
        .again,.practice-bottom-next {
            font-family: PingFangSC, PingFang SC;
            font-weight: 500;
            font-size: 16px;
            color: #0CB76C;
            line-height: 22px;
            text-align: right;
            font-style: normal;
        }
    }
}
.practiceBottom {
    position: fixed;
    width: 100%;
    bottom: 0;
    height: 28px;
    background: #E7F8F0;
    color: #0CB76C;
    font-size: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 20px;
    box-sizing: border-box;

    .again,
    .next {
        width: 80px;
        height: 22px;
        line-height: 22px;
        text-align: center;
        border-radius: 18px;
        border: 1px solid #0CB76C;
    }
}
.practiceFractionBox {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 0 20px;

    .practiceFraction {
        display: inline-block;
        font-size: 28px;

        img {
            width: 55px;
            height: 12px;
            margin-bottom: 6px;
        }

        .context {
            margin-top: 5px;
            display: flex;
            align-items: center;
            color: #8E8E8E;
            font-size: 12px;

            .lebel {
                margin-right: 6px;
            }
        }
    }
}
.circle-progress {
    width: 100%;
    height: 100%;
}

.circle-bg {
    stroke: #FFFFFF;
    /* 背景圆线条颜色 */
}

.circle1,.circle {
    /* 动画定义 */
    animation: progress 8s ease-out forwards;
}

@keyframes progress {
    0% {
        stroke-dashoffset: 100.48;
        /* 初始时，线条完全不可见 */
    }

    100% {
        stroke-dashoffset: 0;
        /* 结束时，线条完全可见 */
    }
}

.van-overlay {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    z-index: 200;

    .initialImg {
        width: 375px;
        height: 260px;
    }

    .initialDiv {
        width: 102px;
        height: 32px;
        line-height: 32px;
        text-align: center;
        font-size: 12px;
        border: 1px solid #FFFFFF;
        color: #FFFFFF;
        border-radius: 18px;
        position: relative;
        top: 30px;
    }
}
.practiceButton {
    height: 52px;
    margin-top: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0 20px 20px;
    position: fixed;
    width: 100%;
    bottom: 28px;
    box-sizing: border-box;
    background-color: #FFFFFF;

    .wordsVoice {
        flex: 1;
        text-align: center;

        img {
            width: 26px;
            height: 20px;
        }
    }

    .wordsPlay {
        flex: 1;
        text-align: center;
        display: flex;
        justify-content: center;
        align-items: center;
        img {
            width: 52px;
            height: 52px;
        }
    }

    .myVoice {
        flex: 1;
        text-align: center;
        display: flex;
        justify-content: center;
        img {
            width: 26px;
            height: 26px;
        }
    }

    .complete {
        font-size: 16px;
        color: #0CB76C;
        margin-left:10px;
    }
}
.circle-container1 {
    width: 40px;
    /* 容器大小，根据需要调整 */
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.automaticOverlay {
    width: 345px;
    height: 184px;
    background: #FFFFFF;
    border-radius: 15px;
    color: #333333;
    font-size: 16px;
    line-height: 32px;

    .automaticOverlay-context {
        margin: 30px 20px;
    }

    .automaticOverlay-button {
        margin: 0 20px 30px 20px;
        display: flex;
        justify-content: space-between;
        align-items: center;

        div {
            width: 135px;
            height: 40px;
            line-height: 40px;
            text-align: center;
        }

        div:nth-child(1) {
            border: 1px solid #8E8E8E;
            border-radius: 22.5px;
            font-size: #333333;
        }

        div:nth-child(2) {
            border-radius: 22.5px;
            color: #FFFFFF;
            background: linear-gradient(to left, #29F19C, #02A1F9);
        }
    }

}
.practice-bottom-img {
    width: 18px;
    height: 18px;
}
::v-deep .van-slider__button {
    display: none !important;
}

.autoRed {
    color: #FA192C !important;
}

.autoYellow {
    color: #FF9917 !important;
}

.autoGreed {
    color: #0CB76C !important;
}
</style>